package com.sys.common.sse;

import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author LGY
 * Create by 2025/4/16 19:27
 */
@Slf4j
@Component
public class SseComponent {

    @Resource(name = "myExecutor")
    private ThreadPoolExecutor executor;

    private static final Map<String, SseEmitter> emitters = new ConcurrentHashMap<>(1000);

    public Map<String, SseEmitter> getCurrentEmitters() {
        return emitters;
    }

    public boolean isClientConnected(String clientId, String type, String custom) {
        return emitters.containsKey(String.format("%s_%s_%s", custom, type, clientId));
    }

    /**
     * 注册一个新的客户端连接，并返回对应的 SseEmitter
     */
    public SseEmitter registerClient(String clientId, String type, String custom) {
        log.info("注册一个新的客户端连接，clientId:{}, type:{},custom:{}", clientId, type, custom);
        // 设置超时时间（毫秒），默认是 30s，这里设置为 1 小时
        SseEmitter emitter = new SseEmitter(3600_000L);
        // 当 emitter 完成或超时时，从 map 中移除
        emitter.onCompletion(() -> emitters.remove(String.format("%s_%s_%s", custom, type, clientId)));
        emitter.onTimeout(() -> emitters.remove(String.format("%s_%s_%s", custom, type, clientId)));
        // 将 emitter 存入 map
        emitters.put(String.format("%s_%s_%s", custom, type, clientId), emitter);
        return emitter;
    }

    /**
     * 向指定 clientId 的客户端发送消息
     */
    public void sendMessageAsync(String clientId, String type, String custom, String message) {
        executor.execute(() -> sendMessage(clientId, type, custom, message));
    }

    /**
     * 向指定 clientId 的客户端发送消息
     */
    public void sendMessage(String clientId, String type, String custom, String message) {
        log.info("给客户端：{},type:{}, custom:{}, 发送消息：{}", clientId, type, custom, message);
        SseEmitter emitter = emitters.get(String.format("%s_%s_%s", custom, type, clientId));
        if (emitter == null) {
            log.info("未找到类型：{}，custom:{}, clientId：{} ", type, custom, clientId);
            return;
        }
        try {
            // 发送消息
            emitter.send(message);
        } catch (IOException e) {
            // 发送失败，可能是客户端已断开连接
            emitters.remove(String.format("%s_%s_%s", custom, type, clientId));
            log.error("给类型：{}，custom:{} clientId：{}客户端发送消息异常", type, custom, clientId, e);
        }
    }
}
